package rate_limit


import "time"


type Limiter struct{
	rate  int // 每秒秒生成的令牌数，例如每秒5个令牌
	cap int // 令牌桶的容量
	tokens float64 // 目前还剩令牌数量，浮点数，而且可以为小于0
	last time.Time // 上次生成令牌的时间
}

func NewLimiter(rate int, cap int) *Limiter{
	return &Limiter{
		rate: rate,
		cap: cap,
		tokens: 0,
		last: time.Now(),
	}
}

//生成这么多令牌需要多少时间
func(limiter *Limiter) durationFormToken(token float64) time.Duration{
	n := token / float64(limiter.rate) // 需要多少秒
	return time.Duration(n * float64(time.Second))
}

func (limiter *Limiter) WaitN(n int){
	now := time.Now()
	// 从上一次索取令牌到现在，一共产生了多少新的令牌
	dalta := now.Sub(limiter.last).Seconds() * float64(limiter.rate)

	// 当前最新的令牌数量
	tokens := limiter.tokens + dalta
	if tokens > float64(limiter.cap){
		tokens = float64(limiter.cap)
	}
	// 减去要索取的令牌数量
	tokens -= float64(n)
	limiter.tokens = tokens
	// 及时更新last
	limiter.last = now

	if tokens < 0 {
		// 剩余的令牌数量不足，需要等待一段时间才能继续索取
		time.Sleep(limiter.durationFormToken(-tokens))
	}
}